import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
import { CreateCourseOfferingDto } from './dto/create-course_offering.dto';
import { UpdateCourseOfferingDto } from './dto/update-course_offering.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { CourseOffering } from './entities/course_offering.entity';
import { Repository } from 'typeorm';
import { Course } from 'src/course/entities/course.entity';
import { Teacher } from 'src/teacher/entities/teacher.entity';
import { Semester } from 'src/semester/entities/semester.entity';
import { QueryCourseOfferingDto } from './dto/query-course-offering.dto';

@Injectable()
export class CourseOfferingService {
  constructor(
    @InjectRepository(CourseOffering)
    private readonly offeringRepo: Repository<CourseOffering>,
    @InjectRepository(Course)
    private readonly courseRepo: Repository<Course>,
    @InjectRepository(Teacher)
    private readonly teacherRepo: Repository<Teacher>,
    @InjectRepository(Semester)
    private readonly semesterRepo: Repository<Semester>
  ) {}

  async create(createDto: CreateCourseOfferingDto) {
    const course = await this.courseRepo.findOne({
      where: { cno: createDto.cno },
      relations: ['teacher']
    });
    const semester = await this.semesterRepo.findOneBy({ semester_id: createDto.semester_id });

    if (!course || !semester) {
      throw new NotFoundException('关联数据不存在');
    }

    // 创建时自动关联课程的教师
    const offering = this.offeringRepo.create({
      course,
      semester,
      teacher: course.teacher,  // 使用课程的教师
      capacity: createDto.capacity,
      location: createDto.location
    });

    return this.offeringRepo.save(offering);
  }

  async findAll(query: QueryCourseOfferingDto) {
    const { page = 1, pageSize = 10, ...filters } = query;
    const skip = (page - 1) * pageSize;

    const queryBuilder = this.offeringRepo.createQueryBuilder('offering')
        .leftJoinAndSelect('offering.course', 'course')
        .leftJoinAndSelect('offering.teacher', 'teacher')
        .leftJoinAndSelect('offering.semester', 'semester');

    // 添加过滤条件
    if (filters.semester_id) {
        queryBuilder.andWhere('offering.semester_id = :semester_id', { semester_id: filters.semester_id });
    }
    if (filters.cno) {
        queryBuilder.andWhere('offering.cno = :cno', { cno: filters.cno });
    }
    if (filters.tno) {
        queryBuilder.andWhere('offering.tno = :tno', { tno: filters.tno });
    }
    if (filters.status) {
        queryBuilder.andWhere('offering.status = :status', { status: filters.status });
    }

    const [list, itemCount] = await queryBuilder
        .skip(skip)
        .take(pageSize)
        .orderBy('offering.offering_id', 'DESC')
        .getManyAndCount();

    return {
        list,
        itemCount,
        page: page.toString(),
        pageSize: pageSize.toString(),
        pageCount: Math.ceil(itemCount / pageSize)
    };
  }

  async findOne(id: number): Promise<CourseOffering> {
    const offering = await this.offeringRepo.findOne({
      where: { offering_id: id },
      relations: ['course', 'teacher', 'semester']
    });
    
    if (!offering) {
      throw new NotFoundException(`开课记录 #${id} 不存在`);
    }
    return offering;
  }

  async update(id: number, updateDto: UpdateCourseOfferingDto): Promise<CourseOffering> {
    const existing = await this.findOne(id);
    
    // 只允许更新容量、位置和状态
    const allowedUpdates = ['capacity', 'location', 'status'];
    const updates = {};
    
    for (const key of allowedUpdates) {
      if (updateDto[key] !== undefined) {
        updates[key] = updateDto[key];
      }
    }

    const updated = await this.offeringRepo.preload({
      offering_id: id,
      ...updates
    });

    if (updated) {
      return this.offeringRepo.save(updated);
    } else {
      throw new NotFoundException(`开课记录 #${id} 无法更新，记录可能不存在`);
    }
  }

  // 获取教师开课列表
  async findByTeacher(tno: number, semester_id?: number) {
    const queryBuilder = this.offeringRepo.createQueryBuilder('offering')
        .leftJoinAndSelect('offering.course', 'course')
        .leftJoinAndSelect('offering.semester', 'semester')
        .where('offering.tno = :tno', { tno });

    if (semester_id) {
        queryBuilder.andWhere('offering.semester_id = :semester_id', { semester_id });
    }

    return queryBuilder.getMany();
  }

  async updateStatus(id: number, status: 'open' | 'closed' | 'cancelled') {
    const offering = await this.findOne(id);
    offering.status = status;
    return this.offeringRepo.save(offering);
  }

  async remove(id: number): Promise<void> {
    const result = await this.offeringRepo.delete(id);
    if (result.affected === 0) {
      throw new NotFoundException(`开课记录 #${id} 不存在`);
    }
  }

  async findBySemester(semester_id: number) {
    return this.offeringRepo.find({
      where: { semester: { semester_id } },
      relations: ['course', 'course.teacher', 'semester'],
      order: { offering_id: 'DESC' }
    });
  }
}
